import { HttpException, HttpStatus, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { toEntity } from "src/utils/dto2Entity";
import { Repository } from "typeorm";
import { RoleDto } from "./dto/role.dto";
import { SearchRoleDto } from "./dto/search-role.dto";
import { RoleEntity } from "./entities/role.entity";
import { PageResponseResult } from "@/common/tools/page.response.result";
import { TenantService } from "@/modules/tenant/tenant.service";

@Injectable()
export class RoleService {
  constructor(private readonly tenantService: TenantService) {}
  @InjectRepository(RoleEntity)
  private readonly roleRepository: Repository<RoleEntity>;

  /**
   * 获取角色分页列表
   * @param searchRoleDto 搜索dto
   */
  async getRolePageList(tenantId: number, searchRoleDto: SearchRoleDto) {
    const { page, keyword } = searchRoleDto;
    const { current, size } = page;
    const skip = (current - 1) * size;
    const tenantRepository = await this.getTenantRepository(tenantId);
    const queryBuilder = tenantRepository.createQueryBuilder("u");
    if (keyword) {
      queryBuilder.where(`u.role_name=:roleName`, { roleName: keyword });
      queryBuilder.orWhere(`u.phone=:phone`, { phone: keyword });
    }
    const entities = await queryBuilder
      .orderBy("u.create_time", "DESC")
      .offset(skip)
      .limit(size)
      .getMany();
    page.total = await queryBuilder.getCount();
    const result = new PageResponseResult<RoleEntity[]>(page.total, entities);
    return result;
  }

  /**
   * 获取角色列表
   */
  async getRoleList(tenantId: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entities = await tenantRepository.find();
    return entities;
  }

  /**
   * 根据用户id获取用户信息
   * @param id 编号
   */
  async getRoleById(tenantId: number, id: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entity = await tenantRepository.findOne({
      where: {
        id,
      },
    });
    return entity;
  }

  /**
   * 根据用户名称获取用户信息
   * @param userName 用户名称
   */
  async getRoleByRoleName(tenantId: number, roleName: string) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entity = await tenantRepository.findOneBy({
      roleName,
    });
    return entity;
  }

  /**
   * 创建角色
   * @param userDto 角色dto
   */
  async createRole(tenantId: number, roleDto: RoleDto) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const role = await tenantRepository.findOneBy({
      roleName: roleDto.roleName,
    });
    if (role) {
      throw new HttpException("操作失败,角色名已使用.", HttpStatus.BAD_REQUEST);
    }
    const roleEntity = new RoleEntity();
    toEntity(roleDto, roleEntity);
    roleEntity.createTime = new Date();
    await tenantRepository.insert(roleEntity);
  }

  /**
   * 修改角色
   * @param id 编号
   * @param userDto 角色dto
   */
  async updateRoleById(tenantId: number, id: number, updateRoleDto: RoleDto) {
    const role = await this.getRoleById(tenantId, id);
    if (!role) {
      throw new HttpException(
        "操作失败,未找到角色信息.",
        HttpStatus.BAD_REQUEST
      );
    }
    const roleEntity = new RoleEntity();
    toEntity(updateRoleDto, roleEntity);
    const tenantRepository = await this.getTenantRepository(tenantId);
    await tenantRepository.update(id, roleEntity);
  }

  /**
   * 删除角色
   * @param id 编号
   */
  async removeRoleById(tenantId: number, id: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    await tenantRepository.delete(id);
  }
  private async getTenantRepository(
    tenantId: number
  ): Promise<Repository<RoleEntity>> {
    const tenantConnection = await this.tenantService.getTenantConnection(
      tenantId
    );
    return tenantConnection.getRepository(RoleEntity);
  }
}
